var gulp = require("gulp"),
    sass = require("gulp-sass"),
    plumber = require("gulp-plumber"),
    rename = require("gulp-rename"),
    gutil = require("gulp-util"),
    uglify = require("gulp-uglify"),
    minifyCss = require("gulp-minify-css"),
    autoprefixer = require("gulp-autoprefixer"),
    inject = require("gulp-inject"),
    concat = require("gulp-concat"),
    // mapstream = require("map-stream"),
    path = require("path"),
    fs = require("fs"),
    del = require("del"),
    browserify = require("browserify"),
    source = require("vinyl-source-stream"),
    watchify = require("watchify"),
    coffeeify = require("coffeeify"),
    // coffeeify = require("gulp-coffeeify"),
    // us = require("underscore"),
    browserSync = require("browser-sync"),
    connect = require("gulp-connect"),
    _ = require("lodash");
// shell = require("gulp-shell"),
// karma = require("karma").server;

var env = (function() {
    var env = {
        // htmlPath: './view',
        lib: {
            path: './lib',
            distPath: './lib/dist',
            configFile: './lib/lib.json',
            distCss: 'lib.css',
            distJs: 'lib.js'
        },
        moduleCoffeeFolder: 'coffee',
        moduleScssFolder: 'scss',
        modules: []
    };

    var dirs = fs.readdirSync('./modules');
    _.each(dirs, function(dir) {
        if (dir == 'common') {
            return
        }
        var module = {
            name: dir,
            path: './modules/' + dir + '/',
            coffee: path.join(env.moduleCoffeeFolder, dir + '.coffee'),
            scss: path.join(env.moduleScssFolder, dir + '.scss'),
            jsFolder: 'js',
            cssFolder: 'css',
            distFolder: 'dist',
            html: dir + '.html'
        };
        if (dir == 'index') {
            module.path = './';
            module.coffee = 'modules/index/coffee/' + dir + '.coffee';
            module.scss = 'modules/index/scss/' + dir + '.scss';
            module.jsFolder = 'modules/index/js';
            module.cssFolder = 'modules/index/css';
            module.distFolder = 'modules/index/dist';
        }
        env.modules.push(module);
    });
    // console.log(env.modules);
    env.scss = [], env.html = [];
    _.each(env.modules, function(module) {
        var moduleCss = module.path + module.scss;
        env.scss.push(moduleCss);

        var moduleHtml = module.path + module.html;
        env.html.push(moduleHtml);
    });
    // console.log(env.js);
    return env;
})();

gulp.task('coffee', function() {
    // var entries = env.js;
    _.each(env.modules, function(module) {
        var entry = module.path + module.coffee,
            jsFolder = module.path + module.jsFolder,
            browserifyOptions = _.extend(watchify.args, {
                debug: true,
                extensions: ['.js', '.json', '.coffee']
            });
        var bundler = watchify(browserify(entry, browserifyOptions));
        bundler.transform(coffeeify);
        rebundle = function() {
            gutil.log(module.name + ' rebundling...');
            bundler.bundle()
                .on('error', gutil.log.bind(gutil, 'Browserify Error'))
                .pipe(source(module.name + '.js'))
                .pipe(gulp.dest(jsFolder))
                .pipe(browserSync.reload({
                    stream: true
                }));
            gutil.log(module.name + 'rebundled');
        }
        bundler.on("update", rebundle);
        // console.log(entries);
        return rebundle()
    })
});


gulp.task('scss', function() {
    // entries = env.css
    _.each(env.modules, function(module) {
        var entry = module.path + module.scss,
            cssFolder = module.path + module.cssFolder;
        gulp.src(entry)
            .pipe(plumber())
            .pipe(sass({
                // imagePath: '../asset/bg',
                outputStyle: 'nested'
            }))
            .pipe(autoprefixer({
                browsers: ['last 2 versions'],
                cascade: true
            }))
            // .pipe(gulp.dest(envs.buildDir))
            // .pipe(rename(envs.buildCss))
            .pipe(gulp.dest(cssFolder))
            .pipe(browserSync.reload({
                stream: true
            }));
    });
});

gulp.task('lib-css', function() {
    var lib = require(env.lib.configFile),
        libCss = [];
    _.each(lib, function(v, k) {
        libCss = _.union(libCss, v.css);
    });
    libCss.push(env.lib.path + '/css/**/*.css');
    return gulp.src(libCss).pipe(concat(env.lib.distCss)).pipe(gulp.dest(env.lib.distPath));
});

gulp.task('lib-js', function() {
    var lib = require(env.lib.configFile),
        libJs = [];
    _.each(lib, function(v, k) {
        libJs = _.union(libJs, v.js);
    });
    libJs.push(env.lib.path + '/js/**/*.js');
    return gulp.src(libJs).pipe(concat(env.lib.distJs)).pipe(gulp.dest(env.lib.distPath));
});

gulp.task('lib', ['lib-css', 'lib-js']);

gulp.task('browserSync', function() {
    var bsOption = {
        port: 9000,
        proxy: "http://localhost:8080",
        online: true,
        open: false,
        watchOptions: {
            debounceDelay: 1000
        },
        ghostMode: {
            links: false
        },
        logConnections: true,
        logLevel: "debug"
    };
    browserSync(bsOption);
});

gulp.task("connect", function() {
    connect.server({
        port: 8080
    });
});

gulp.task('html', function() {
    entries = env.html
    gulp.src(entries)
        .pipe(browserSync.reload({
            stream: true
        }));
});

gulp.task('watch', ['connect', 'browserSync', 'coffee'], function() {
    gulp.watch(env.scss, ['scss']);
    // gulp.watch(path.join(envs.srcDir,'vendor.css'),['vendor-css']);
    // gulp.watch(env.js, ['coffee']);
    // gulp.watch(envs.srcTpl, ['tpl']);
    gulp.watch(env.html, ['html']);
    // gulp.watch(path.join(envs.srcDir,'vendor.js'),['vendor-js']);
});

gulp.task('min-js', function() {
    var timestamp = '-' + _.now();
    _.each(env.modules, function(module) {
        del.sync(path.join(module.path, module.distFolder + '/*.js'));
        jsFile = path.join(module.path, module.jsFolder + '/*.js')
        gulp.src(jsFile)
            .pipe(uglify())
            .pipe(rename(function(path) {
                path.basename += timestamp;
            }))
            .pipe(gulp.dest(module.path + module.distFolder));
    });
});


gulp.task('min-css', function() {
    var timestamp = '-' + _.now();
    _.each(env.modules, function(module) {
        del.sync(path.join(module.path, module.distFolder + '/*.css'));
        cssFile = path.join(module.path, module.cssFolder + '/*.css')
            // console.log(cssFile);
        gulp.src(cssFile)
            .pipe(minifyCss({
                keepBreaks: true
            }))
            .pipe(rename(function(path) {
                path.basename += timestamp;
            }))
            .pipe(gulp.dest(module.path + module.distFolder));
    });
});
gulp.task('min', ['min-js', 'min-css']);

gulp.task("deploy", function() {
    _.each(env.modules, function(module) {
        var injectTarget = path.join(module.path, module.html),
            cssFiles = [],
            jsFiles = [];
        cssFiles.push(path.join(env.lib.distPath, '/*.css'));
        jsFiles.push(path.join(env.lib.distPath, '/*.js'));
        cssFiles.push(path.join(module.path, module.distFolder + '/*.css'));
        jsFiles.push(path.join(module.path, module.distFolder + '/*.js'));
        var sources = gulp.src(_.union(cssFiles, jsFiles), {
            read: false
        });
        // if (module.name == "index") {
        gulp.src(injectTarget).pipe(inject(sources)).pipe(gulp.dest(module.path));
        // } else {
        // gulp.src(injectTarget).pipe(inject(sources)).pipe(gulp.dest(env.htmlPath));
        // }
    });
});
gulp.task("develop", function() {
    _.each(env.modules, function(module) {
        var injectTarget = path.join(module.path, module.html),
            cssFiles = [],
            jsFiles = [];
        // console.log(cssFiles);
        cssFiles.push(path.join(env.lib.distPath, '/*.css'));
        jsFiles.push(path.join(env.lib.distPath, '/*.js'));
        cssFiles.push(path.join(module.path, module.cssFolder + '/*.css'));
        jsFiles.push(path.join(module.path, module.jsFolder + '/*.js'));
        var sources = gulp.src(_.union(cssFiles, jsFiles), {
            read: false
        });
        gulp.src(injectTarget).pipe(inject(sources)).pipe(gulp.dest(module.path));
    });
});
